import Obj3D from '../js/Poly2/Obj3D.js';
import Geo from '../js/Poly2/Geo.js';
import Mat from '../js/Poly2/Mat.js';
import { Matrix4, Vector3 } from './three.module.js';

const defAttr = () => ({
    count: 0,//粒子的数量
    diff: [0, 0],//外扩长度, 飞行长度
    program: '',
    gl: null,

    color1: [0, 1, 1, 0.5],
    color2: [1, 1, 1, 0.5],
});

//粒子
export default class Particle {
    constructor(attr) {
        Object.assign(this, defAttr(), attr);
    }

    getElement(point) {
        return this._createParticle(point, this.count);
    }

    _createParticle(point, count) {
        let particle = new Obj3D();

        for (let i = 0; i < count; i++) {
            const configs = this._createTriangleConfigOfDouble(point);
            particle.add(this.gl, this._createTriangleOfDouble(configs));
        }
        return particle;
    }

    //创建三角形配制
    _createTriangleConfigOfDouble(point) {
        const { color1, color2 } = this;
        const angles = [Math.random() * 360, Math.random() * 70 * -1];
        const size = [20, Math.random() * 30 + 20];
        const posiArr = this._getNodePosi(point);

        const configTriangle1 = {
            a_Position: point,
            u_PosiMove: [posiArr[0].x, posiArr[0].y, posiArr[1].x, posiArr[1].y],
            u_Angle: angles,
            u_PointSize: size,
            u_Opaque: [0.3, 0.5],
            u_Diff: 0.8,
            color: color1,
        };

        const configTriangle2 = {
            a_Position: point,
            u_PosiMove: [posiArr[0].x, posiArr[0].y, posiArr[1].x, posiArr[1].y],
            u_Angle: angles,
            u_PointSize: [size[0], size[1] * 0.6],
            u_Opaque: [0.3, 0.5],
            u_Diff: 0.9,
            color: color2,
        };
        return [configTriangle1, configTriangle2];
    }

    //计算开始点与结束点
    _getNodePosi(point) {
        const { diff } = this;

        const j = Math.random() * 360 * Math.PI / 180;
        //开始点
        let jcd_x = diff[0];
        let jcd_l = jcd_x * Math.cos(j);
        let jcd_d = jcd_x * Math.sin(j);
        let jcd = new Vector3(jcd_d, jcd_l, 0).add(point);
        //结束点
        let jsd_x = diff[0] + Math.random() * diff[1];
        let jsd_l = jsd_x * Math.cos(j);
        let jsd_d = jsd_x * Math.sin(j);
        let jsd = new Vector3(jsd_d, jsd_l, 0).add(point);

        return [jcd, jsd];
    }

    //创建双层三角形
    _createTriangleOfDouble(configs) {

        const objW = this._createTriangle(configs[0]);
        const objB = this._createTriangle(configs[1]);
        objW.add(this.gl, objB);

        return objW;
    }

    //创建三角形对象
    _createTriangle(config) {
        const {
            u_PointSize, color,
            a_Position, u_PosiMove,
            u_Angle, u_Diff, u_Opaque
        } = config;
        const { program } = this;
        return new Obj3D({
            geo: new Geo({
                data: {
                    'a_Position': { size: 2, array: new Float32Array([a_Position.x, a_Position.y]) },
                }
            }),
            mat: new Mat({
                program: program,
                mode: ['POINTS'],
                data: {
                    'u_Color': { type: 'uniform4fv', value: color },
                    'u_PointSize': { type: 'uniform2fv', value: u_PointSize },
                    'u_Angle': { type: 'uniform2fv', value: u_Angle },
                    'u_Opaque': { type: 'uniform2fv', value: u_Opaque },
                    'u_Set': { type: 'uniform1f', value: 0 },
                    'u_Diff': { type: 'uniform1f', value: u_Diff },
                    'u_PosiMove': { type: 'uniform4fv', value: u_PosiMove },
                },
            }),
        });
    }
}